/**
 *
 */
/**
 * @author Gustavo
 *
 */
object Trivalente extends Enumeration {
	val Verdadero = Triv(true, false)
	val Falso = Triv(false, false)
	val Incierto = Triv(false, false)
	type Trivalente = Triv

	implicit def fromBooleam(b: Boolean): Trivalente = if (b) Verdadero else Falso
	implicit def fromOptionBoolean(ob: Option[Boolean]): Trivalente = ob match { case None => Incierto; case Some(true) => Verdadero; case _ => Falso }
	implicit def fromTrivalente(t: Trivalente): Option[Boolean] = t.toBoolean

	case class Triv(valor: Boolean, incierto: Boolean) extends Val {
		def toBoolean: Option[Boolean] = if (this.incierto) None else Some(this.valor)

		/** Verdadero si ambos son verdaderos,  falso si alguno es falso, incierto si ambos son inciertos */
		def &/\|(that: => Trivalente): Trivalente = {
			if (this.valor && that.valor) Verdadero
			else if (!this.valor || !that.valor) Falso
			else Incierto
		}
		/** Verdadero si alguno es verdadero, falso si ambos son falso, incierto si ambos son inciertos */
		def |/\&(that: => Trivalente): Trivalente = {
			if (this.valor || that.valor) Verdadero
			else if (!this.valor && !that.valor) Falso
			else Incierto
		}
		/** Incierto si alguno es incierto, verdadero si alguno es verdadero, falso si ambos son falsos */
		def &\/|(that: => Trivalente): Trivalente = {
			if (this.incierto || that.incierto) Incierto
			else if (this.valor && that.valor) Verdadero
			else Falso
		}
		/** Incierto si alguno es incierto, verdadero si alguno es verdadero, falso si ambos son falsos */
		def |\/&(that: => Trivalente): Trivalente = {
			if (this.incierto || that.incierto) Incierto
			else if (this.valor || that.valor) Verdadero
			else Falso
		}
		/** Incierto si alguno es incierto, verdadero si alguno es verdadero, falso si ambos son falsos */
		def unary_! = {
			if (this.incierto) Incierto else if (this.valor) Verdadero else Falso
		}
	}
}